package tools

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

//定义全局的db对象，我们执行数据库操作主要通过他实现。
var db *gorm.DB

//包初始化函数，golang特性，每个包初始化的时候会自动执行init函数，这里用来初始化gorm。
func init() {
	fmt.Println("init")
	//配置MySQL连接参数
	username := "root"  //账号
	password := "root" //密码
	host := "192.168.42.200" //数据库地址，可以是Ip或者域名
	port := 3306 //数据库端口
	Dbname := "portscan" //数据库名

	//通过前面的数据库参数，拼接MYSQL DSN， 其实就是数据库连接串（数据源名称）
	//MYSQL dsn格式： {username}:{password}@tcp({host}:{port})/{Dbname}?charset=utf8&parseTime=True&loc=Local
	//类似{username}使用花括号包着的名字都是需要替换的参数
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", username, password, host, port, Dbname)
	//连接MYSQL
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	if err != nil {
		panic("连接数据库失败, error=" + err.Error())
	}
	sqlDB, _ := db.DB()

	//设置数据库连接池参数
	sqlDB.SetMaxOpenConns(100)   //设置数据库连接池最大连接数
	sqlDB.SetMaxIdleConns(20)   //连接池最大允许的空闲连接数，如果没有sql任务需要执行的连接数大于20，超过的连接会被连接池关闭


	if db == nil {
		panic("GetDB, error=" + err.Error())
	}
}

//获取gorm db对象，其他包需要执行数据库查询的时候，只要通过tools.getDB()获取db对象即可。
//不用担心协程并发使用同样的db对象会共用同一个连接，db对象在调用他的方法的时候会从数据库连接池中获取新的连接
func GetDB() *gorm.DB {
	return db
}


func create_first_table_user(){
	fmt.Println(db)
	db.AutoMigrate(&User{})
	fmt.Println("Hello, 我在 utilset 目录下的 utils 包里")

}

//定义User模型，绑定users表，ORM库操作数据库，需要定义一个struct类型和MYSQL表进行绑定或者叫映射，struct字段和MYSQL表字段一一对应
//在这里User类型可以代表mysql users表
type User struct {
	ID int64 // 主键
	//通过在字段后面的标签说明，定义golang字段和表字段的关系
	//例如 `gorm:"column:username"` 标签说明含义是: Mysql表的列名（字段名)为username
	//这里golang定义的Username变量和MYSQL表字段username一样，他们的名字可以不一样。
	Username string `gorm:"column:username"`
	Password string `gorm:"column:password"`
	//创建时间，时间戳
	CreateTime int64 `gorm:"column:createtime"`
}

//设置表名，可以通过给struct类型定义 TableName函数，返回当前struct绑定的mysql表名是什么
func (u User) TableName() string {
	//绑定MYSQL表名为users
	return "users"
}

//func main()  {
//
//	//配置MySQL连接参数
//	//username := "root"  //账号
//	//password := "root" //密码
//	//host := "192.168.42.200" //数据库地址，可以是Ip或者域名
//	//port := 3306 //数据库端口
//	//Dbname := "portscan" //数据库名
//
//	//通过前面的数据库参数，拼接MYSQL DSN， 其实就是数据库连接串（数据源名称）
//	//MYSQL dsn格式： {username}:{password}@tcp({host}:{port})/{Dbname}?charset=utf8&parseTime=True&loc=Local
//	//类似{username}使用花括号包着的名字都是需要替换的参数
//	//dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", username, password, host, port, Dbname)
//	//连接MYSQL
//	//db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
//	db := GetDB()
//
//	//if err != nil {
//	//	panic("连接数据库失败, error=" + err.Error())
//	//}
//
//
//
//	//定义一个用户，并初始化数据
//	u := User{
//		Username:"tizi365",
//		Password:"123456",
//		CreateTime:time.Now().Unix(),
//	}
//
//	//插入一条用户数据
//	//下面代码会自动生成SQL语句：INSERT INTO `users` (`username`,`password`,`createtime`) VALUES ('tizi365','123456','1540824823')
//	if err := db.Create(&u).Error; err != nil {
//		fmt.Println("插入失败", err)
//		return
//	}
//
//	//查询并返回第一条数据
//	//定义需要保存数据的struct变量
//	u = User{}
//	//自动生成sql： SELECT * FROM `users`  WHERE (username = 'tizi365') LIMIT 1
//	result := db.Where("username = ?", "tizi365").First(&u)
//	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
//		fmt.Println("找不到记录")
//		return
//	}
//	//打印查询到的数据
//	fmt.Println(u.Username,u.Password)
//
//	//更新
//	//自动生成Sql: UPDATE `users` SET `password` = '654321'  WHERE (username = 'tizi365')
//	db.Model(&User{}).Where("username = ?", "tizi365").Update("password", "654321")
//
//	//删除
//	//自动生成Sql： DELETE FROM `users`  WHERE (username = 'tizi365')
//	db.Where("username = ?", "tizi365").Delete(&User{})
//}
//

func PrintHello(){
	fmt.Println("Hello, 我在 utilset 目录下的 utils 包里")
}